package com.xplay.xpocker.service.gaming.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xplay.xpocker.config.security.CurrentUser;
import com.xplay.xpocker.constant.RoomTypeEnum;
import com.xplay.xpocker.dvo.GameRoomStruct;
import com.xplay.xpocker.entity.GameRuRoomDTO;
import com.xplay.xpocker.exception.ServiceAssertion;
import com.xplay.xpocker.exception.StatusCodeEnum;
import com.xplay.xpocker.room.mahjong.dto.MahjongStatusEnum;
import com.xplay.xpocker.entity.GameRuRoom;
import com.xplay.xpocker.entity.GameRuRoomUser;
import com.xplay.xpocker.mapper.GameRuRoomMapper;
import com.xplay.xpocker.room.message.AbstractMessageStrategy;
import com.xplay.xpocker.room.message.MessageContent;
import com.xplay.xpocker.service.gaming.GameRuRoomService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xplay.xpocker.service.gaming.GameRuRoomUserService;
import com.xplay.xpocker.util.Assertion;

import com.xplay.xpocker.util.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xplay
 * @since 2023-08-18
 */
@Service
public class GameRuRoomServiceImpl extends ServiceImpl<GameRuRoomMapper, GameRuRoom> implements GameRuRoomService {
    @Autowired
    private GameRuRoomUserService ruRoomUserService;


    @Override
    public GameRuRoom createRoom(String code, String type, String metaData) {
        //创建房间
        GameRuRoom gameRuRoom = new GameRuRoom();
        gameRuRoom.setCreateDate(new Date());
        gameRuRoom.setCreater(CurrentUser.getUsername());
        gameRuRoom.setCode(code);
        gameRuRoom.setUserId(CurrentUser.getUserId());
        gameRuRoom.setType(type);
        RoomTypeEnum typeEnum = RoomTypeEnum.of(type);
        gameRuRoom.setName(typeEnum.name);
        gameRuRoom.setStatus(MahjongStatusEnum.CREATING.getStatus());
        gameRuRoom.setMetadata(metaData);
        gameRuRoom.setSeveralInning(0);
        save(gameRuRoom);
        //加入房间
        ruRoomUserService.addHome(CurrentUser.getUserId(), gameRuRoom.getId());
        return gameRuRoom;
    }

    @Override
    public GameRuRoom queryRoomByCode(String roomCode) {
        LambdaQueryWrapper<GameRuRoom> roomWrap = Wrappers.lambdaQuery(GameRuRoom.class).eq(GameRuRoom::getCode, roomCode);
        GameRuRoom gameRuRoom = getOne(roomWrap);
        ServiceAssertion.isNull(gameRuRoom, StatusCodeEnum.ROOM_NOT_FOUND);
        return gameRuRoom;
    }

    @Override
    public GameRuRoom currentUserRoom() {
        BigDecimal userId = CurrentUser.getUserId();
        LambdaQueryWrapper<GameRuRoomUser> exits = Wrappers.lambdaQuery(GameRuRoomUser.class).eq(GameRuRoomUser::getUserId, userId);
        List<GameRuRoomUser> users = ruRoomUserService.list(exits);
        if (ObjectUtils.isEmpty(users)) {
            return null;
        }
        GameRuRoomUser gameRuRoomUser = users.get(0);
        return getById(gameRuRoomUser.getRoomId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doMessage(MessageContent<Object> content) {
        GameRuRoom gameRuRoom = currentUserRoom();
        Assertion.isNull(content, "消息有误");
        Assertion.isNull(content.getType(), "消息有误");
        AbstractMessageStrategy strategy = AbstractMessageStrategy.messageHandler.get(content.getType());
        Assertion.isNull(strategy, "消息有误");
        strategy.doMessage(gameRuRoom.getCode(), content);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserState(Boolean hook, Boolean online) {
        BigDecimal userId = CurrentUser.getUserId();
        LambdaQueryWrapper<GameRuRoomUser> exits = Wrappers.lambdaQuery(GameRuRoomUser.class).eq(GameRuRoomUser::getUserId, userId);
        List<GameRuRoomUser> users = ruRoomUserService.list(exits);
        Assertion.isNull(users, "用户不在房间内");
        GameRuRoomUser gameRuRoomUser = users.get(0);
        if (hook != null) {
            gameRuRoomUser.setOnHook(hook);
        }
        if (online != null) {
            gameRuRoomUser.setOnline(online);
        }
        ruRoomUserService.updateById(gameRuRoomUser);
    }

    @Override
    public GameRuRoomDTO queryRoomRuInfo(String roomCode) {
        LambdaQueryWrapper<GameRuRoom> roomWrap = Wrappers.lambdaQuery(GameRuRoom.class).eq(GameRuRoom::getCode, roomCode);
        GameRuRoom gameRuRoom = getOne(roomWrap);
        GameRuRoomDTO roomDTO = GameRoomStruct.INSTANCE.rd(gameRuRoom);
        LambdaQueryWrapper<GameRuRoomUser> exits = Wrappers.lambdaQuery(GameRuRoomUser.class).eq(GameRuRoomUser::getRoomId, roomDTO.getId());
        roomDTO.setAllUsers(ruRoomUserService.list(exits));
        return roomDTO;
    }


}
